/**
 * 
 */
package com.nari.baseinfo.dao;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.hibernate.Query;

import com.nari.baseinfo.model.IBuilding;
import com.nari.coreframe.dao.hibernate3.GenericDaoImpl;
import com.nari.platform.model.PageCond;
import com.nari.platform.model.ResponseMsg;
import com.nari.platform.model.ResultWithPageCond;
import com.nari.rescontroller.dao.IResourceAccessControlDao;

/**
 * 
 * @author Xiaopeng  
 * @date 2013-8-1
 */
public class BuildingDaoImpl extends GenericDaoImpl<IBuilding, String> implements IBuildingDao {
	private IResourceAccessControlDao iResourceAccessControlDao;
	
	/**
	 * 分页查询楼栋信息
	 * @param buildingName 楼栋名称(可选)
	 * @param projectUID 所属项目(可选)
	 * @param communityUID 所属小区(可选)
	 * @param pageCond
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-8
	 */
	@SuppressWarnings("unchecked")
	public ResultWithPageCond<IBuilding> queryBuildingPage(String buildingName, String projectUID, 
			String communityUID, PageCond pageCond) throws Exception {
		String listHql = "from IBuilding b where 1=1";
		//楼栋名称
		if(buildingName!=null && !"".equals(buildingName.trim())) {
			listHql += " and lower(b.buildingName) like '%"+buildingName.trim().toLowerCase()+"%'";
		}
		//所属项目
		if(projectUID!=null && !"".equals(projectUID.trim())) {
			listHql += " and b.projectID='"+projectUID.trim()+"'";
		}
		//所属小区
		if(communityUID!=null && !"".equals(communityUID.trim())) {
			listHql += " and b.communityID='"+communityUID.trim()+"'";
		}
		//权限资源匹配
		String authorityRes = iResourceAccessControlDao.queryAuthorityProjResHql();
		if(!"".equals(authorityRes)) {
			listHql += " and b.projectID in("+authorityRes+")";
		}
		//统计结果集个数
		String countHql = "select count(*) " + listHql;
		int total = ((Long)this.getCurrentSession().createQuery(countHql).uniqueResult()).intValue();
		//结果集排序
		listHql += " order by b.buildingID asc,b.buildingName asc";
		//结果集分页
		Query listQuery = this.getCurrentSession().createQuery(listHql);
		listQuery.setFirstResult(pageCond.getStart()).setMaxResults(pageCond.getLimit());
		//构造返回类型
		pageCond.setTotal(total);
		ResultWithPageCond<IBuilding> buildingPage = new ResultWithPageCond<IBuilding>();
		buildingPage.setList(listQuery.list());
		buildingPage.setPageCond(pageCond);
		return buildingPage;
	}
	
	/**
	 * 根据楼栋所属信息（所属项目、所属小区）查询楼栋列表
	 * 若项目ID、小区ID都不存在，则返回空列表
	 * @param projectUID 所属项目
	 * @param communityUID 所属小区
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-12
	 */
	public List<IBuilding> queryBuildingByBelongings(String projectUID, 
			String communityUID) throws Exception {
		//若项目ID、分摊域ID都不存在，则返回空列表
		if((projectUID==null || "".equals(projectUID))
				&& (communityUID==null || "".equals(communityUID))) {
			return new ArrayList<IBuilding>();
		}
		String listHql = "from IBuilding b where 1=1";
		//所属项目
		if(projectUID!=null && !"".equals(projectUID.trim())) {
			listHql += " and b.projectID='"+projectUID.trim()+"'";
		}
		//所属小区
		if(communityUID!=null && !"".equals(communityUID.trim())) {
			listHql += " and b.communityID='"+communityUID.trim()+"'";
		}
		//权限资源匹配
		String authorityRes = iResourceAccessControlDao.queryAuthorityProjResHql();
		if(!"".equals(authorityRes)) {
			listHql += " and b.projectID in("+authorityRes+")";
		}
		//结果集排序
		listHql += " order by b.buildingID asc,b.buildingName asc";
		return this.runQueryHSql(listHql);
	}
	
	/**
	 * 通过楼栋ID列表查询楼栋信息
	 * @param idList 楼栋ID列表，若列表为空，则返回空列表
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-13
	 */
	public List<IBuilding> queryBuildingByIDList(List<String> idList) throws Exception {
		if(idList!=null && idList.size()>0) {
			StringBuffer hsql = new StringBuffer("select distinct b from IBuilding b ");
			hsql.append("where b.id in(");
			for(int index=0; index<idList.size(); index++) {
				hsql.append("'");
				hsql.append(idList.get(index));
				hsql.append("'");
				if(index < idList.size()-1) {
					hsql.append(",");
				}
			}
			hsql.append(") ");
			hsql.append("order by b.buildingID,b.buildingName");
			return this.runQueryHSql(hsql.toString());
		}
		return null;
	}
	
	/**
	 * 通过楼栋ID列表查询楼栋ID-楼栋名称映射表
	 * @param idList 楼栋ID列表，若列表为空，则返回一个空映射表
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-8-13
	 */
	public Map<String, String> queryIdNameMapByIDList(List<String> idList) throws Exception {
		Map<String, String> idNameMap = new HashMap<String, String>();
		if(idList!=null && idList.size()>0) {
			StringBuffer hsql = new StringBuffer("select distinct b.id,b.buildingID ");
			hsql.append("from IBuilding b ");
			hsql.append("where b.id in(");
			for(int index=0; index<idList.size(); index++) {
				hsql.append("'");
				hsql.append(idList.get(index));
				hsql.append("'");
				if(index < idList.size()-1) {
					hsql.append(",");
				}
			}
			hsql.append(")");
			List<Object> resultsList = this.runQueryHSqlObject(hsql.toString());
			//格式化查询结果集
			if(resultsList!=null && resultsList.size()>0) {
				for(Object result: resultsList) {
					Object[] arrayMap = (Object[]) result;
					idNameMap.put(arrayMap[0].toString(), arrayMap[1].toString());
				}
			}
		}
		return idNameMap;
	}
	
	/**
	 * 通过楼栋所属关系统计楼栋的个数
	 * @param projectUID 所属项目(可选)
	 * @param communityUID 所属小区(可选)
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2013-10-21
	 */
	public int countBuildingSumByBelongs(String projectUID, String communityUID) throws Exception {
		String countHql = "select count(*) from IBuilding b where 1=1";
		//所属项目
		if(projectUID!=null && !"".equals(projectUID.trim())) {
			countHql += " and b.projectID='"+projectUID.trim()+"'";
		}
		//所属小区
		if(communityUID!=null && !"".equals(communityUID.trim())) {
			countHql += " and b.communityID='"+communityUID.trim()+"'";
		}
		//权限资源匹配
		String authorityRes = iResourceAccessControlDao.queryAuthorityProjResHql();
		if(!"".equals(authorityRes)) {
			countHql += " and b.projectID in("+authorityRes+")";
		}
		return ((Long)this.getCurrentSession().createQuery(countHql).uniqueResult()).intValue();
	}
	
	/**
	 * 通过楼栋编号查询楼栋信息
	 * @param buildingID
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-1-12
	 */
	public IBuilding queryBuildingInfoByBuildingID(String buildingID) throws Exception {
		String hsql = "from IBuilding b where b.buildingID='"+buildingID+"'";
		List<IBuilding> buildingList = this.runQueryHSql(hsql);
		//楼栋信息
		IBuilding building = null;
		if(buildingList!=null && buildingList.size()>0) {
			building = buildingList.get(0);
		}
		return building;
	}
	
	/**
	 * 根据楼栋ID级联删除关联信息
	 * 包括：楼栋、单元、热用户、系统用户及角色、热量表、分配表、散热器、温度点、用户分摊账单
	 * 注意：热量表数据、分配表数据等表计数据具有不可恢复性，因此不能作为级联删除的对象
	 * @param buildingUID
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-1-20
	 */
	public ResponseMsg deleteCascadeByBuildingUID(String buildingUID) throws Exception {
		//删除楼栋所属散热器
		String delSinkerHql = "delete from PSinkInfo sink " +
				"where sink.roomId in(select hr.id " +
									"from IHeatRoom hr " +
									"where hr.buildingID='"+buildingUID+"')";
		this.runFormatHSql(delSinkerHql);
		//删除楼栋所属分配表
		String delAssignMeterHql = "delete from IAssignMeter am " +
				"where am.roomId in(select hr.id " +
								"from IHeatRoom hr " +
								"where hr.buildingID='"+buildingUID+"')";
		this.runFormatHSql(delAssignMeterHql);
		//删除楼栋所属的温度点
		String delTempPointHql = "delete from ITemperaturePoint tp " +
				"where tp.buildingID='"+buildingUID+"'";
		this.runFormatHSql(delTempPointHql);
		//删除楼栋所属热量表
		String delHeatMeterHql = "delete from IHeatMeter hm " +
				"where hm.buildingID='"+buildingUID+"'";
		this.runFormatHSql(delHeatMeterHql);
		//删除楼栋所属用户分摊账单
		String delSinkResultHql = "delete from IShareSinkResult ssr " +
				"where ssr.userShareResultID in(select usr.id " +
											"from IUserShareResult usr " +
											"where usr.buildingID='"+buildingUID+"')";
		this.runFormatHSql(delSinkResultHql);
		String delUserResultHql = "delete from IUserShareResult usr " +
				"where usr.buildingID='"+buildingUID+"'";
		this.runFormatHSql(delUserResultHql);
		//删除楼栋所属楼栋单元
		String delUnitHql = "delete from IBuildingUnit bu " +
				"where bu.buildingID='"+buildingUID+"'";
		this.runFormatHSql(delUnitHql);
		//删除楼栋所属系统用户、用户角色
		String delUserRoleHql = "delete from IUserRole ur " +
				"where ur.userUuid in(select u.id " +
									"from IUser u " +
									"where u.roomId in(select hr.id " +
													"from IHeatRoom hr " +
													"where hr.buildingID='"+buildingUID+"'))";
		this.runFormatHSql(delUserRoleHql);
		String deleteUserHql = "delete from IUser u " +
				"where u.roomId in(select hr.id " +
								"from IHeatRoom hr " +
								"where hr.buildingID='"+buildingUID+"')";
		this.runFormatHSql(deleteUserHql);
		//删除楼栋所属热用户
		String delRoomHql = "delete from IHeatRoom hr " +
				"where hr.buildingID='"+buildingUID+"'";
		this.runFormatHSql(delRoomHql);
		//删除楼栋所属集中器
		String delConcentratorHql = "delete from IConcentrator con " +
				"where con.buildingID='"+buildingUID+"'";
		this.runFormatHSql(delConcentratorHql);
		//删除楼栋信息
		this.deleteEntityById(buildingUID);
		return ResponseMsg.getInstance(true, "");
	}
	
	/**
	 * 统计相同楼栋编号的楼栋数量，避免系统录入相同楼栋编号的楼栋信息
	 * @param buildingID
	 * @param buildingUID
	 * @return
	 * @throws Exception
	 * @author Xiaopeng
	 * @date 2014-1-22
	 */
	public int countByBuildingID(String buildingID, String buildingUID) throws Exception {
		String hsql = "select count(*) from IBuilding b " +
				"where b.buildingID='"+buildingID+"'";
		if(buildingUID!=null && !"".equals(buildingUID)) {
			hsql += " and b.id<>'"+buildingUID+"'";
		}
		int counter = ((Long)this.getCurrentSession().createQuery(hsql).uniqueResult()).intValue();
		return counter;
	}

	/**
	 * @return the iResourceAccessControlDao
	 */
	public IResourceAccessControlDao getiResourceAccessControlDao() {
		return iResourceAccessControlDao;
	}

	/**
	 * @param iResourceAccessControlDao the iResourceAccessControlDao to set
	 */
	public void setiResourceAccessControlDao(
			IResourceAccessControlDao iResourceAccessControlDao) {
		this.iResourceAccessControlDao = iResourceAccessControlDao;
	}
	
}
